package wang.hex;

import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.regex.Pattern;


/**
 * @Author fox
 * @Class SimpleLogger
 * @Description
 * @Date 2020/12/24 13:11
 */
public class SimpleLogger {
    private String path;
    private FileWriter fileWriter;
    public long lastUseTimestamp = System.currentTimeMillis();

    private static Map<Class, Function<Object, String>> arrayResovleMap = new HashMap<>();

    private static List<SimpleLogger> list = new LinkedList<>();

    static {
        arrayResovleMap.put(int[].class, o -> Arrays.toString((int[]) o));
        arrayResovleMap.put(String[].class, o -> Arrays.toString((String[]) o));
        arrayResovleMap.put(byte[].class, o -> Arrays.toString((byte[]) o));
        arrayResovleMap.put(short[].class, o -> Arrays.toString((short[]) o));
        arrayResovleMap.put(long[].class, o -> Arrays.toString((long[]) o));
        arrayResovleMap.put(float[].class, o -> Arrays.toString((float[]) o));
        arrayResovleMap.put(double[].class, o -> Arrays.toString((double[]) o));
        arrayResovleMap.put(boolean[].class, o -> Arrays.toString((boolean[]) o));
        arrayResovleMap.put(char[].class, o -> Arrays.toString((char[]) o));
        arrayResovleMap.put(Object[].class, o -> Arrays.toString((Object[]) o));

        //释放空闲的文件
        Executors.newFixedThreadPool(1).execute(() -> {
            while (true) {
                long timeMillis = System.currentTimeMillis();
                list.forEach(item -> {
                    if (timeMillis - item.lastUseTimestamp > 3000) {
                        item.close();
                    }
                });
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });

    }

    private SimpleLogger(String path) {
        this.path = path;

    }

    public static SimpleLogger getLogger(String path) {
        SimpleLogger simpleLogger = new SimpleLogger(path);
        list.add(simpleLogger);
        return simpleLogger;
    }

    public static String formatLogger(String format, Object... args) {

        String[] array = new String[args.length];
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            if (arg == null) {
                array[i] = "";
                continue;
            }
            Function<Object, String> function = arrayResovleMap.get(arg.getClass());
            if (function != null) {
                array[i] = function.apply(arg);
            } else {
                if (arg instanceof Exception) {
                    array[i] = ((Exception) arg).getCause().getMessage();
                } else {
                    array[i] = arg.toString();
                }
            }
        }
        return String.format(format, array);
    }

    public void close() {
        if (fileWriter != null) {
            try {
                fileWriter.close();
                fileWriter = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void logger(String s, Object... args) {
        writeToFile(formatLogger(s, args));
    }

    private void writeToFile(String context) {
        if (context == null) {
            return;
        }
        lastUseTimestamp = System.currentTimeMillis();
        if (fileWriter == null) {
            synchronized (this) {
                try {
                    if (fileWriter == null) {
                        fileWriter = new FileWriter(path, true);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            fileWriter.write(context + "\n");
            fileWriter.flush();
        } catch (Exception e) {

        }
    }


}
